using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace Zsa.Emulation.Processor
{
    /// <summary>
    /// Persistable cpu state.
    /// </summary>
    [Serializable(),
    StructLayout(LayoutKind.Sequential)]
    public struct Cpu6502State
    {
        #region Fields
        /// <summary>
        /// The program register.
        /// </summary>
        private readonly ushort _RegisterProgramCounter;
        
        /// <summary>
        /// The accumulator register.
        /// </summary>
        private readonly byte _RegisterAccumulator;

        /// <summary>
        /// RegisterX
        /// </summary>
        private readonly byte _RegisterX;

        /// <summary>
        /// Register Y.
        /// </summary>
        private readonly byte _RegisterY;

        /// <summary>
        /// The stack pointer.
        /// </summary>
        private readonly byte _RegisterStackPointer;

        /// <summary>
        /// The status register.
        /// </summary>
        private readonly StatusRegisterFlags _RegisterStatus;

        #endregion Fields

        #region Constructors
        /// <summary>
        /// Initializes a new instance of the <see cref="T:Cpu6502State"/> class.
        /// </summary>
        /// <param name="programCount">The program count.</param>
        /// <param name="regAcc">The reg acc.</param>
        /// <param name="regX">The reg X.</param>
        /// <param name="regY">The reg Y.</param>
        /// <param name="regSP">The reg SP.</param>
        /// <param name="regStatus">The reg status.</param>
        public Cpu6502State(ushort programCount,
            byte regAcc, byte regX, byte regY, byte regSP, 
            byte regStatus)
            : this(programCount, regAcc, regX, regY, regSP, (StatusRegisterFlags)regStatus)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="T:Cpu6502State"/> class.
        /// </summary>
        /// <param name="programCount">The program count.</param>
        /// <param name="regAcc">The reg acc.</param>
        /// <param name="regX">The reg X.</param>
        /// <param name="regY">The reg Y.</param>
        /// <param name="regSP">The reg SP.</param>
        /// <param name="regStatus">The reg status.</param>
        public Cpu6502State(ushort programCount,
            byte regAcc, byte regX, byte regY, byte regSP, StatusRegisterFlags regStatus)
        {
            _RegisterProgramCounter = programCount;
            _RegisterAccumulator = regAcc;
            _RegisterStackPointer = regSP;
            _RegisterStatus = regStatus;
            _RegisterX = regX;
            _RegisterY = regY;
        }

        #endregion Constructors

        #region Properties
        /// <summary>
        /// Gets the register program counter.
        /// </summary>
        /// <value>The register program counter.</value>
        public ushort RegisterProgramCounter
        {
            get { return _RegisterProgramCounter; }
        }
        /// <summary>
        /// Gets the register accumulator.
        /// </summary>
        /// <value>The register accumulator.</value>
        public byte RegisterAccumulator
        {
            get { return _RegisterAccumulator; }
        }
        /// <summary>
        /// Gets the register X.
        /// </summary>
        /// <value>The register X.</value>
        public byte RegisterX
        {
            get { return _RegisterX; }
        }
        /// <summary>
        /// Gets the register Y.
        /// </summary>
        /// <value>The register Y.</value>
        public byte RegisterY
        {
            get { return _RegisterY; }
        }
        /// <summary>
        /// Gets the register stack pointer.
        /// </summary>
        /// <value>The register stack pointer.</value>
        public byte RegisterStackPointer
        {
            get { return _RegisterStackPointer; }
        }
        /// <summary>
        /// Gets the register status.
        /// </summary>
        /// <value>The register status.</value>
        public StatusRegisterFlags RegisterStatus
        {
            get { return _RegisterStatus; }
        }
        #endregion Properties

        #region Methods

        /// <summary>
        /// Returns the fully qualified type name of this instance.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.String"></see> containing a fully qualified type name.
        /// </returns>
        public override string ToString()
        {
            return string.Format(
                "PC : {0} RegAcc : {1} RegX : {2} RegY : {3} RegSp : {4} RegStatus : {5}",
                _RegisterProgramCounter,
                _RegisterAccumulator,
                _RegisterX,
                _RegisterY,
                _RegisterStackPointer,
                _RegisterStatus
            );

        }


        #endregion Methods
    }
}
